<template>
  <div class="hello">
    hello-vue3
    <p>{{ name }}</p>
    <ul>
      <li v-for="item in arr" :key="item">{{ item }}</li>
    </ul>
    <ul>
      <li v-for="item in onlyRead" :key="item">{{ item }}</li>
    </ul>
    <p @click="emitClick(msgaa)">{{ msgaa }}</p>
    <p @click="count += 1">count:{{count}} --- 计算属性:{{doubleCount}}</p>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, reactive, readonly, toRefs, h, computed } from 'vue'
export default defineComponent({
  name: 'CommonVueCompnt',
  props: {
    rnm: Number
  },
  // created 在实例被完全初始化之前
  setup (props, context) {
    /*
     props: Props
     context: {attrs,emit, slots }
        -attrs:父组件传递None_Props
        -slots: 插槽VNode对象，可以用h渲染
     */
    console.log('Props:', props)
    const { attrs, emit, slots } = context
    console.log('attrs:', attrs)
    console.log('slots:', slots.default!())
    const emitClick = (param:string) => emit('mounted', param)
    // ref处理基础类型, 利用proxy实现(转换成一个对象{value:"sam"})，修改数据需要通过[name].value修改
    const name = ref('sam')
    // reactive处理可监听类型, 利用proxy实现
    const arr = reactive(['hhh', 'lalal'])
    // readonly限制响应式数据的修改
    const onlyRead = readonly(reactive(['我是你爹']))
    // toRefs将Proxy({a:xxx})转换为{a:proxy{xxx}} 说白了就是子属性(数组元素)转换响应式
    /*
    还有一个类似的toRef(reactiveObj,"PropertyName")可以动态添加属性(即Property可以是不存在的，不咋常用)
     */
    const [msgaa] = toRefs(reactive(['我是你爹']))

    // 计算属性Demo
    const count = ref(0)
    /* const doubleCount = computed(() => {
      return count.value * 2
    }) */
    const doubleCount = computed({
      get: () => count.value * 2,
      set: (newVal) => { count.value = newVal }
    })

    setTimeout(() => {
      name.value = 'lone'
      arr.push('wtf?')
      // onlyRead.push('????')
      msgaa.value = 'NPM???'
      doubleCount.value = 10
    }, 3000)
    return {
      name,
      arr,
      onlyRead,
      msgaa,
      emitClick,
      count,
      doubleCount
    }
    // 返回一个函数调用h渲染函数，会替换掉template的内容
    // return () => h('div', {}, [slots.default!()])
  }
})
</script>

<style scoped>

</style>
